package Cam5zyx0715;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;

public class DrawMouse implements ActionListener,MouseListener {
    public Graphics g;
    private Graphics bg;

    private BufferedImage bufferedImage;
    public String fn;//= "D:\\JAVAproject\\idea\\BeautyCam\\src\\Cam3zyx0711\\flower.jpg";
    public String str;

    public JPanel j1=null;
    public int s=1 ;

    public int a,b;

    // 添加一个变量来跟踪旋转角度
    private int rotationAngle = 0;

    public void mouseClicked(MouseEvent e){
        int x =a= e.getX();
        int y =b= e.getY();

    }
    public void mousePressed(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}






    public void actionPerformed(ActionEvent e) {
        String btnStr = e.getActionCommand();
        str = btnStr;
        System.out.println("用户点击了" + btnStr+"按钮......");
        System.out.println("稍等一会，图片效果马上呈现");
        //根据字符串绘制相关图片
        switch (btnStr) {
            case "原图":
                oripic();
                break;
            case "灰度"://取rgb平均值，则画成灰度图
                grey();
                break;
            case "二值化":
                binarization();
                break;
            case "马赛克":
                mosaic();
                break;
            case"放大":
                Todouble();
                break;
            case"缩小":
                narrow();
                break;
            case"油画":
                oil();
                break;
            case"哈哈镜":
                funhouseMirror();
                break;
            case "旋转":
                spin();
                rotationAngle +=35;
                break;
            case "撤销":
                undoImage();
                break;
        }
    }

        //程序的执行过程：代码 > jvm > os > 总线 > 显示器
        //创建缓冲区 把所有的像素点显示在缓存去上
        public void bufferZone() {
            int[][] data = image(fn);
            bufferedImage = new BufferedImage( data.length, data[0].length,BufferedImage.TYPE_INT_RGB);
            bg = bufferedImage.getGraphics();
            bg.setColor(Color.WHITE);
            bg.fillRect(0,0,bufferedImage.getWidth(),bufferedImage.getHeight());
    }



       public void oripic(){
           bufferZone();
           int[][] data = image(fn);//图片放在项目目录下
           for (int i = 0; i < data.length; i++) {
                for (int j = 0; j < data[i].length; j++) {
                    //得到颜色值，画出每一个点
                    Color c = new Color(data[i][j]);
                    bg.setColor(c);//g.setColor(new Color(data[i][j])）；
                    bg.fillOval(i / 2, j /2, 2, 2);
                }
            }

            //把缓冲区显示在窗体；
            g.drawImage(bufferedImage,0,22,j1);
        }
    public void grey(){
       bufferZone();
       int[][] data = image(fn);
        for (int i = 0; i < data.length; i++){
            for (int j = 0; j < data[i].length; j++){
                Color color = new Color(data[i][j]);
                int red = color.getRed();
                int green = color.getGreen();
                int blue = color.getBlue();
                int sum = (red+green+blue)/3;
                Color newColor = new Color(sum,sum,sum);
                bg.setColor(newColor);
                bg.drawOval(i/2,j/2,1,1);
            }
        }
        //把缓冲区显示在窗体；
        g.drawImage(bufferedImage,0,22,j1);
    }

    public void mosaic() {
        bufferZone();
        int x = s;
      int[][] data = image(fn);
        for (int i = 0; i < data.length; i += (15+1.6*x)) {
            for (int j = 0; j < data[i].length; j += (15+1.6*x)) {
                Color color = new Color(data[i][j]);
                bg.setColor(color);
                bg.fillRect(i / 2, j/ 2, 15, 15);
            }
        }
        //把缓冲区显示在窗体；
        g.drawImage(bufferedImage,0,22,j1);
    }

    public void binarization() {
        bufferZone();
        int x = s;
        int[][] data = image(fn);
        int h = data.length;
        int w = data[0].length;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                int p = data[i][j];
                Color color = new Color(p);
                int blue = color.getBlue();
                if (blue >(70+2*x)){
                    bg.setColor(Color.BLACK);
                }else{
                    bg.setColor(Color.WHITE);
                }
                bg.drawOval(i/2,j/2,1,1);
            }
        }
        System.out.println(70+x);
        //把缓冲区显示在窗体；
        g.drawImage(bufferedImage,0,22,j1);
    }

    public void narrow(){
       bufferZone();
       int x = s;
       int[][] data = image(fn);//图片放在项目目录下
        int w= data.length;
        int h=data[0].length;
        for (int i = 0; i < w; i+=2) {
            for (int j = 0; j < h; j+=2) {
                //得到颜色值，画出每一个点
                Color c = new Color(data[i][j]);
                bg.setColor(c);//g.setColor(new Color(data[i][j])）；
                bg.fillRect(i/(2*x) , j/(2*x), x, x);
            }
        }
        g.drawImage(bufferedImage, 0, 22, j1);

    }
    public void Todouble(){
        bufferZone();
        int x = s;
       int[][] data = image(fn);//图片放在项目目录下
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                //得到颜色值，画出每一个点
                Color c = new Color(data[i][j]);
                bg.setColor(c);//g.setColor(new Color(data[i][j])）；
                bg.fillRect(i*(x/2)/2, j *(x/2)/2, x, x);
            }
        }
        g.drawImage(bufferedImage, 0, 22, j1);

    }

    public void oil(){
        bufferZone();
        int x = s;
        int[][] data = image(fn);
        for (int i =0; i < data.length-5; i +=5){
            for (int j =0; j < data[i].length-5; j +=5) {
                Color color = new Color(data[i][j]);
                bg.setColor(color);
                Random ran=new Random();
                int r1 = ran.nextInt(20)*x+5;
                int r2 = ran.nextInt(40)*x+5;
                bg.fillOval((i+x)/2, (j+x)/2,Math.max(r1,r2), Math.min(r1,r2));
            }
        }
        //把缓冲区显示在窗体；
        g.drawImage(bufferedImage,0,22,j1);
    }


    public void funhouseMirror() {
        bufferZone();
        int x = s;
        int[][] data = image(fn);
        int h=data.length;
        int w=data[0].length;
        int maxDist = (int) Math.sqrt((w/2 - a) * (w/2 - a) + (h/2 - b) * (h/2 - b));
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                int deltaX = i - b;
                int deltaY = j - a;
                double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
                int newX = (int) (i + deltaX * x * maxDist / distance*0.1);
                int newY = (int) (j + deltaY * x * maxDist / distance*0.1);

                if (newX >= 0 && newX < data.length && newY >= 0 && newY < data[i].length) {
                    Color color = new Color(data[newX][newY]);
                    bg.setColor(color);
                    bg.drawOval(i/2, j/2, 1, 1);
                }
            }
        }
        // 把缓冲区显示在窗体；
        g.drawImage(bufferedImage, 0, 22, j1);
    }


    public void spin() {
        bufferZone();
        int[][] data = image(fn);
        int width = data.length;
        int height = data[0].length;
        int[][] rotatedData = new int[width][height];
        int angle = rotationAngle;

        // 计算旋转后的像素位置
        double radians = Math.toRadians(angle);
        double sin = Math.sin(radians);
        double cos = Math.cos(radians);
        int centerX = width / 2;
        int centerY = height / 2;

        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                int deltaX = i - centerX;
                int deltaY = j - centerY;
                int newX = (int) (deltaX * cos - deltaY * sin) + centerX;
                int newY = (int) (deltaX * sin + deltaY * cos) + centerY;

                if (newX >= 0 && newX < width && newY >= 0 && newY < height) {
                    rotatedData[i][j] = data[newX][newY];
                }
            }

        }

        for (int i = 0; i < rotatedData.length; i++) {
            for (int j = 0; j < rotatedData[i].length; j++) {
                Color color = new Color(rotatedData[i][j]);
                bg.setColor(color);
                bg.fillRect(i / 2, j / 2, 2, 2);
            }
        }

        g.drawImage(bufferedImage, 0, 22, j1);
    }
    public void undoImage(){
        bufferZone();
        int[][] data = image(fn);
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                // 将颜色设置为白色以撤销更改
                bg.setColor(Color.WHITE);
                bg.fillRect(i / 2, j / 2, 2, 2);
            }
        }
        // 显示更新后的图像
        g.drawImage(bufferedImage, 0, 22, j1);
    }


    //将一张图片转化一个int型的二维数组
    private int[][] image(String imageName) {
        File file = new File(fn);
        BufferedImage bi = null;
        try {
            bi = ImageIO.read(file); //从文件到图片对象
        } catch (Exception e) {
            e.printStackTrace();
        }
        int w = bi.getWidth(); //图片的宽
        int h = bi.getHeight(); //图片的高
        int[][] imIndex = new int[w][h];//存像素值的二维数组
        //System.out.println("w=" + w + " h=" + h );
        for (int i = 0; i < w; i++) {
            for (int j = 0; j < h; j++) {
                imIndex[i][j] = bi.getRGB(i, j); //i,j 位置的 Color 值，每个像素点的 color 存入数组
            }
        }
        return imIndex;
    }


}


